#include "GameScene.h"

#include "GameDefine.h"

#include "Server.h"

#ifdef GAME_USEKEYBOARD
#include <windows.h>
#define KEY_DOWN(vk_code) (GetAsyncKeyState(vk_code) & 0x8000 ? 1 : 0)
#define KEY_UP(vk_code) (GetAsyncKeyState(vk_code) & 0x8000 ? 0 : 1)
#endif

#include "IGCHelper.h"
#include <cmath>
#include "Objects.h"

using namespace cocos2d;

CGameScene::CGameScene()
{
    memset(m_szTips, 0, sizeof(m_szTips));
}

//---------------------------------------------------------------------------------------------------/
void CGameScene::onEnter()
{
	this->setIsTouchEnabled(true);
	this->setIsAccelerometerEnabled(true);

	m_pLayMain = CCLayer::node();
	CCSprite *pSprBack = CCSprite::spriteWithFile("map.png");
	pSprBack->setPosition(ccp(SCREEN_WIDTH*0.5f, SCREEN_HEIGHT*0.5f));
	m_pLayMain->addChild(pSprBack);
	addChild(m_pLayMain, 10);

	m_pLayUI = CCLayer::node();
	addChild(m_pLayUI, 20);

	InitBars();
    
    m_pLabel = CCLabelTTF::labelWithString("tips", "Terminal", 30);
    m_pLabel->setPosition(ccp(300, 50));
    m_pLayUI->addChild(m_pLabel);

    

#ifdef GAME_USERAKNET
	m_bGameStart   = false;
	char szID[ID_MAX_LENGTH];
	GCGetDeviceID(szID);
#else
	m_bGameStart = true;
#endif
	m_bServer      = false;

#ifdef GAME_USEKEYBOARD
	CClient::GetInstance()->SetClientDelegate(this);
	CClient::GetInstance()->SetTempServer(CServer::GetInstance());
#else
    
    CServer::GetInstance()->SetClientHelper(CClient::GetInstance());
	CClient::GetInstance()->Open(szID, this);
    CGameTimer::SetInterval(200);

#endif
	
	
	m_player.InitState(this, m_pLayMain, 10, ccp(BOXER_DOWN_INIT_X, BOXER_DOWN_INIT_Y), &m_opponent, true);
	m_opponent.InitState(this, m_pLayMain, 10, ccp(BOXER_UP_INIT_X, BOXER_UP_INIT_Y), &m_player, false);
	
	schedule(schedule_selector(CGameScene::Tick));
   
    
#if (CC_TARGET_PLATFORM == CC_PLATFORM_IOS)
	//GCInit();
	//GCFindPlayer(2, 2, this);
    
	
#endif

	CCLayer::onEnter();
}

//---------------------------------------------------------------------------------------------------/
void CGameScene::onExit()
{

}

//---------------------------------------------------------------------------------------------------/
void CGameScene::didAccelerate(CCAcceleration* pAccelerationValue)
{
	m_ptAcc.x = (float)pAccelerationValue->x;
	m_ptAcc.y = (float)pAccelerationValue->y;
}

//---------------------------------------------------------------------------------------------------/
void CGameScene::ccTouchesBegan(CCSet *pTouches, CCEvent *pEvent)
{
	if(pTouches->count() < 1)
	{
		return;
	}

	//int count = pTouches->count();

	CCTouch *pTouch = (CCTouch*)pTouches->anyObject();
    
    if(m_bGameStart)
    {
        if(CCRect::CCRectContainsPoint(CCRect(0, 0, SCREEN_WIDTH*0.5f, SCREEN_HEIGHT), m_pLayMain->convertTouchToNodeSpace(pTouch)))
        {
            if(m_player.AttackWithLeft())
            {
                ClientPacket p;
                if(m_bServer)
                {
                    p.m_side = CLIENT_SIDE_DOWN;
                }
                else
                {
                    p.m_side = CLIENT_SIDE_UP;
                }
                
                p.m_command = COMMAND_ATTACK_LEFT;
                CClient::GetInstance()->SendClientCommand(p);
            }
        }
        else
        {
            if(m_player.AttackWithRight())
            {
                ClientPacket p;
                if(m_bServer)
                {
                    p.m_side = CLIENT_SIDE_DOWN;
                }
                else
                {
                    p.m_side = CLIENT_SIDE_UP;
                }
                
                p.m_command = COMMAND_ATTACK_RIGHT;
                CClient::GetInstance()->SendClientCommand(p);
            }
        }
    }

}

//---------------------------------------------------------------------------------------------------/
void CGameScene::ccTouchesEnded(CCSet *pTouches, CCEvent *pEvent)
{

}

//---------------------------------------------------------------------------------------------------/
void CGameScene::PlayerLocalHurt()
{

}

//---------------------------------------------------------------------------------------------------/
void CGameScene::PlayerOppoentHurt()
{

}

//---------------------------------------------------------------------------------------------------/
void CGameScene::InitBars()
{
	for(int i=0; i<2; i++)
	{
		m_pSprBarBlankBlood[i]  = CCSprite::spriteWithFile("barBlank.png");
		m_pSprBarBlankSprite[i] = CCSprite::spriteWithFile("barBlank.png");
		m_pSprBarBlood[i]       = CCSprite::spriteWithFile("barBlood.png");
		m_pSprBarSprite[i]      = CCSprite::spriteWithFile("barSprite.png");

		m_pLayUI->addChild(m_pSprBarBlankBlood[i]);
		m_pLayUI->addChild(m_pSprBarBlankSprite[i]);
		m_pSprBarBlankBlood[i]->addChild(m_pSprBarBlood[i]);
		m_pSprBarBlankSprite[i]->addChild(m_pSprBarSprite[i]);
		
		m_pSprBarBlood[i]->setAnchorPoint(ccp(0, 0));
		m_pSprBarBlood[i]->setPosition(ccp(0, 0));
		m_pSprBarSprite[i]->setAnchorPoint(ccp(0, 0));
		m_pSprBarSprite[i]->setPosition(ccp(0, 0));
	}
	
	m_pSprBarBlankBlood[0]->setPosition(ccp(200, SCREEN_HEIGHT - 15));
	m_pSprBarBlankBlood[1]->setPosition(ccp(SCREEN_WIDTH - 200, SCREEN_HEIGHT - 15));
	m_pSprBarBlankSprite[0]->setPosition(ccp(200, SCREEN_HEIGHT - 45));
	m_pSprBarBlankSprite[1]->setPosition(ccp(SCREEN_WIDTH - 200, SCREEN_HEIGHT - 45));
}

void CGameScene::UpdateBars()
{

	m_pSprBarBlood[0]->setTextureRect(CCRect(0, 0, 200.0f * m_player.GetHp() / BOXER_HP_MAX, 18));
	m_pSprBarSprite[0]->setTextureRect(CCRect(0, 0, 200.0f * m_player.GetSprite() / BOXER_SPRITE_MAX, 18));

	m_pSprBarBlood[1]->setTextureRect(CCRect(0, 0, 200.0f * m_opponent.GetHp() / BOXER_HP_MAX, 18));
	m_pSprBarSprite[1]->setTextureRect(CCRect(0, 0, 200.0f * m_opponent.GetSprite() / BOXER_SPRITE_MAX, 18));

}

//---------------------------------------------------------------------------------------------------/
void CGameScene::ShowTimeDiff()
{
	timeval time;
	gettimeofday(&time	, NULL);
	static long lastTime = time.tv_sec * 1000 + time.tv_usec / 1000;
	long curTime = time.tv_sec * 1000 + time.tv_usec / 1000;
	CCLOG("localDelay %ld", curTime - lastTime);
	lastTime = curTime;
}

//---------------------------------------------------------------------------------------------------/
void CGameScene::Tick(cocos2d::ccTime dt)
{
	if(m_bGameStart)
	{
#if (CC_TARGET_PLATFORM == CC_PLATFORM_IOS)

        m_player.Update(dt);
		m_opponent.Update(dt);
        
        if(!CGameTimer::IsPrepared())
        {
            return;
        }
        
		m_pLabel->setString(m_szTips);

		
        
        if (m_ptAcc.x > 0.3f) 
        {
            if(m_player.MoveRight())
            {
                ClientPacket p;
                if(m_bServer)
                {
                    p.m_side = CLIENT_SIDE_DOWN;
                }
                else
                {
                    p.m_side = CLIENT_SIDE_UP;
                }
                
                p.m_command = COMMAND_MOVE_RIGHT;
                CClient::GetInstance()->SendClientCommand(p);
            }
        }
        else if(m_ptAcc.x < - 0.3f)
        {
            if(m_player.MoveLeft())
            {
                ClientPacket p;
                if(m_bServer)
                {
                    p.m_side = CLIENT_SIDE_DOWN;
                }
                else
                {
                    p.m_side = CLIENT_SIDE_UP;
                }
                
                p.m_command = COMMAND_MOVE_LEFT;
                CClient::GetInstance()->SendClientCommand(p);
            }
        }
        
        if(m_ptAcc.y < -0.3f)
        {
            if(m_player.Dodge())
            {
                ClientPacket p;
                if(m_bServer)
                {
                    p.m_side = CLIENT_SIDE_DOWN;
                }
                else
                {
                    p.m_side = CLIENT_SIDE_UP;
                }
                
                p.m_command = COMMAND_DODGE;
                CClient::GetInstance()->SendClientCommand(p);
            }
        }
        else if(m_ptAcc.y > -0.2f) 
        {
            if(m_player.DodgeToNormal())
            {
                ClientPacket p;
                if(m_bServer)
                {
                    p.m_side = CLIENT_SIDE_DOWN;
                }
                else
                {
                    p.m_side = CLIENT_SIDE_UP;
                }
                
                p.m_command = COMMAND_DODGETONORMAL;
                CClient::GetInstance()->SendClientCommand(p);
            }
        }
#endif

#if (CC_TARGET_PLATFORM == CC_PLATFORM_WIN32)

		/*
		if(KEY_DOWN(0x57))
		{
		// w
		m_player.Move(ccp(0, BOXER_MOVE_DIST));
		}
		*/

		if(KEY_DOWN(0x53))
		{
			if(m_player.IsValible())
			{
				if(m_player.Dodge())
				{
					ClientPacket p;
					p.m_side = CLIENT_SIDE_DOWN;
					p.m_command = COMMAND_DODGE;
					CClient::GetInstance()->SendClientCommand(p);
				}
			}
			
			// s
			//m_player.Move(ccp(0, -BOXER_MOVE_DIST));
			//m_player.Dodge();
		}
		else
		{
			if(m_player.GetState() == CBoxerClient::STATE_DODGE)
			{
				if(m_player.DodgeToNormal())
				{
					ClientPacket p;
					p.m_side = CLIENT_SIDE_DOWN;
					p.m_command = COMMAND_DODGETONORMAL;
					CClient::GetInstance()->SendClientCommand(p);
				}
			}
			
		}

		if(KEY_DOWN(0x44))
		{
			if(m_player.IsValible())
			{
				if(m_player.MoveRight())
				{
					ClientPacket p;
					p.m_side = CLIENT_SIDE_DOWN;
					p.m_command = COMMAND_MOVE_RIGHT;
					CClient::GetInstance()->SendClientCommand(p);
				}
			}
			
		}

		if(KEY_DOWN(0x41))
		{
			if(m_player.IsValible())
			{
				// a
				if(m_player.MoveLeft())
				{
					ClientPacket p;
					p.m_side = CLIENT_SIDE_DOWN;
					p.m_command = COMMAND_MOVE_LEFT;
					CClient::GetInstance()->SendClientCommand(p);
				}
				
				
			}
			
		}

		if(KEY_DOWN(0x4A))
		{
			if(m_player.IsValible())
			{
				// J
				if(m_player.AttackWithLeft())
				{
					ClientPacket p;
					p.m_side = CLIENT_SIDE_DOWN;
					p.m_command = COMMAND_ATTACK_LEFT;
					CClient *pClient = CClient::GetInstance();
					CClient::GetInstance()->SendClientCommand(p);
					pClient->SendClientCommand(p);
				}
				
				
			}
			
		}

		if(KEY_DOWN(0x4B))
		{
			// K
			if(m_player.IsValible())
			{
				if(m_player.AttackWithRight())
				{
					ClientPacket p;
					p.m_side = CLIENT_SIDE_DOWN;
					p.m_command = COMMAND_ATTACK_RIGHT;
					CClient::GetInstance()->SendClientCommand(p);
				}
			}
			// J

		}

		/*
		if(KEY_DOWN(0x4C))
		{
		// L
		m_player.Defense();
		}
		*/

		if(KEY_DOWN(VK_UP))
		{
			//m_opponent.Move(ccp(0, BOXER_MOVE_DIST));
			if(m_opponent.Dodge())
			{
				ClientPacket p;
				p.m_side = CLIENT_SIDE_UP;
				p.m_command = COMMAND_DODGE;
				CClient::GetInstance()->SendClientCommand(p);
			}
		}
		else
		{
			if(m_opponent.DodgeToNormal())
			{
				ClientPacket p;
				p.m_side = CLIENT_SIDE_UP;
				p.m_command = COMMAND_DODGETONORMAL;
				CClient::GetInstance()->SendClientCommand(p);
			}
		}

		/*
		if(KEY_DOWN(VK_DOWN))
		{
		m_opponent.Move(ccp(0, -BOXER_MOVE_DIST));
		}
		*/

		if(KEY_DOWN(VK_RIGHT))
		{
			if(m_opponent.MoveLeft())
			{
				ClientPacket p;
				p.m_side = CLIENT_SIDE_UP;
				p.m_command = COMMAND_MOVE_LEFT;
				CClient::GetInstance()->SendClientCommand(p);
			}
		}

		if(KEY_DOWN(VK_LEFT))
		{
			if(m_opponent.MoveRight())
			{
				ClientPacket p;
				p.m_side = CLIENT_SIDE_UP;
				p.m_command = COMMAND_MOVE_RIGHT;
				CClient::GetInstance()->SendClientCommand(p);
			}
		}

		if(KEY_DOWN(VK_NUMPAD2))
		{
			if(m_opponent.AttackWithLeft())
			{
				ClientPacket p;
				p.m_side = CLIENT_SIDE_UP;
				p.m_command = COMMAND_ATTACK_LEFT;
				CClient::GetInstance()->SendClientCommand(p);
			}
		}

		if(KEY_DOWN(VK_NUMPAD1))
		{
			if(m_opponent.AttackWithRight())
			{
				ClientPacket p;
				p.m_side = CLIENT_SIDE_UP;
				p.m_command = COMMAND_ATTACK_RIGHT;
				CClient::GetInstance()->SendClientCommand(p);
			}
		}

		/*
		if(KEY_DOWN(VK_NUMPAD3))
		{
		m_opponent.Defense();
		}
		*/

#endif
	}
}

//////////////////////NetworkDelegate/////////////////////
#ifdef GAME_USERAKNET

void CGameScene::connectServerSuccessed()
{
	CCLog("连接服务器成功，正在匹配房间");

	//m_pLabel->setString("连接成功，正在匹配房间");
    CClient::GetInstance()->ConnectRandomRoom();
	strcpy(m_szTips, "连接成功，正在匹配房间");
}

void CGameScene::connectServerFailed()
{
	//m_pLabel->setString("服务器连接失败");
	strcpy(m_szTips, "服务器连接失败");
}

//---------------------------------------------------------------------------------------------------/
void CGameScene::connectLost()
{
	//m_pLabel->setString("丢失连接");
	strcpy(m_szTips, "丢失连接");
}

//---------------------------------------------------------------------------------------------------/
void CGameScene::opponentFound(const BoxerInfo &info)
{
	CCLog("已经发现对手，准备开始游戏");
	strcpy(m_szTips, "开始游戏");

	m_bGameStart = true;
	m_bServer = CClient::GetInstance()->IsHost();
}
#endif

//---------------------------------------------------------------------------------------------------/
void CGameScene::receiveServerInfo(const GameInfo &info)
{
	UpdateCurGameInfo(info);
}   

//---------------------------------------------------------------------------------------------------/
void CGameScene::UpdateCurGameInfo(const GameInfo &info)
{
	// 客户端会接受此信息来更新游戏
    

        
}

void CGameScene::receiveOpponentInfo(const ActionInfo &info)
{
	switch (info.m_action)
	{
	case ID_ACTION_LEFTFIST:
		m_opponent.AttackWithLeft();
		break;

	case ID_ACTION_RIGHTFIST:
		m_opponent.AttackWithRight();
		break;

    case ID_ACTION_CHANGEPOS:
		m_opponent.SetEndX(info.m_xPos);
		m_opponent.SetEndY(info.m_yPos);
            break;
            
        case ID_ACTION_DODGE:
            m_opponent.SetEndX(info.m_xPos);
            m_opponent.SetEndY(info.m_yPos);
            m_opponent.SetDodgePara(4.0f);
            break;
            
            case ID_ACTION_DODGETONORMAL:
            m_opponent.SetEndX(info.m_xPos);
            m_opponent.SetEndY(info.m_yPos);
            m_opponent.SetDodgePara(1.0f);
            break;

	default:
		CCLog("收取信息错误");
		break;
	}	
}



